<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./assets/global.css">
    <link rel="stylesheet" href="./assets/fontawesome/css/all.min.css">
    <style>
        #container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-wrap: wrap;
            height: 100vh;
            align-content: center;
            position: relative;
        }

        #container canvas {
            margin-top: -140px
        }

        .welcome-statement {
            position: absolute;
            top: 100px;
            font-size: 40px;
            color: #999;
        }

        .join-us {
            position: absolute;
            bottom: 200px;
            z-index: 100;
            display: inline-flex;
            padding: 0 20px 3px;
            line-height: 40px;
            background: linear-gradient(to bottom, rgb(87, 196, 245), rgb(26, 147, 206));
            color: rgb(254, 252, 255);
            cursor: pointer;
            border-radius: 4px;
            font-weight: bold;
            box-shadow: inset 0px -3px 0 rgb(19, 98, 139);
        }

        .join-us:active {
            opacity: .7;
            box-shadow: inset 0px 0px 0 transparent;
        }

        .bgm-controller {
            position: absolute;
            right: 20px;
            top: 20px;
            font-size: 40px;
        }

        .bgm-controller:active {
            opacity: .7;
        }
    </style>
</head>

<body>
    <div id="container">
        <video class="bgm" muted style="display: none;">
            <source src="./assets/dance/kemusan.mp4" />
        </video>
        <div class="welcome-statement">感谢各位给 H5.Examples 点⭐⭐~</div>
        <a class="join-us" href="https://github.com/linyisonger/H5.Examples">
            加入我们
        </a>
        <div class="bgm-controller">
            <i class="fas fa-volume-mute"></i>
        </div>
    </div>
    <script type="module">
        /**
        * 加载配置信息
        * @author 	 linyisonger
        * @date 	 2025-02-25
        */
        function fetchLoad(url) {
            return new Promise((resolve) => {
                fetch(url).then((response) => response.json()).then(resolve)
            })
        }

        /**
         * 加载图
         * @param {string} src
         * @returns {Promise<HTMLImageElement>}
         */
        function loadImage(src) {
            return new Promise((resolve) => {
                let image = new Image()
                image.src = src;
                image.onload = (ev) => {
                    resolve(image)
                }
            })
        }

        /**
         * 获取star的用户 默认30一页
         * @author 	 linyisonger
         * @date 	 2025-02-18
         */
        async function getStargazers(page = 1) {
            const result = await fetch(`https://api.github.com/repos/linyisonger/H5.Examples/stargazers?page=${page}`)
            return await result.json()
        }

        /**
         * 获取所有star的用户
         * @author 	 linyisonger
         * @date 	 2025-02-18
         */
        async function getAllStargazers(page = 1, users = []) {
            let stargazers = await getStargazers(page)
            users = users.concat(stargazers)
            if (stargazers.length < 30) return users
            return await getAllStargazers(page + 1, users)
        }


        let bgmControllerDom = document.querySelector('.bgm-controller')
        bgmControllerDom.addEventListener("click", () => {
            const bgm = document.body.querySelector('.bgm')

            const bgmIcon = document.querySelector('.bgm-controller').querySelector('i')
            bgm.muted = !bgm.muted;
            bgmIcon.className = bgm.muted ? 'fas fa-volume-mute' : 'fas fa-volume-up'
        })


        async function init() {
            let dancers = await getAllStargazers() // 加载关注用户信息
            let dance = await fetchLoad("./assets/dance/kemusan.json") // 加载配置
            const DROP_FRAME = 5 // 抽帧
            const ZOOM_OUT = .5 // 缩放

            // 检查动作信息
            // for (let i = 0; i < dance.frames.length; i++) {
            //     console.log(i);
            //     const frame = dance.frames[i];
            //     const img = document.createElement('img')
            //     img.src = frame.url;
            //     document.body.appendChild(img)
            // } 
            // return


            let danceCvsList = [] // 用户画布列表
            for (let i = 0; i < dancers.length; i++) {
                const dancer = dancers[i]; // 单个的用户信息
                let danceCvs = await createCanvas(dancer) // 创建画布
                danceCvsList.push({
                    dancer,
                    cvs: danceCvs
                })
            }


            let i = 0 // 帧
            async function animationFrame() {
                if (i % DROP_FRAME == 0) { // 每几帧进行取余
                    for (let j = 0; j < danceCvsList.length; j++) {
                        const { cvs, dancer } = danceCvsList[j];
                        await drawFrame(cvs, dance.frames[(i / DROP_FRAME) % dance.frames.length], dancer.avatar_url) // 绘制一帧画面
                    }
                }
                requestAnimationFrame(animationFrame)
                i++;
            }
            await animationFrame() // 等待第一张加载完成

            document.body.querySelector('.bgm').play()
            document.body.querySelector('.bgm').loop = true;

            // 依然无法同步音频与动画的频率

            /**
             * 创建一个用户
             * @author 	 linyisonger
             * @date 	 2025-02-23
             */
            function createCanvas(dancer) {
                let avatarUrl = dancer.avatar_url
                let cvs = document.createElement("canvas")
                cvs.setAttribute('width', dance.width)
                cvs.setAttribute('height', dance.height)
                cvs.width = dance.width * ZOOM_OUT;
                cvs.height = dance.height * ZOOM_OUT;
                document.body.querySelector("#container").appendChild(cvs)
                return cvs
            }
            /**
             * 渲染一帧
             * @author 	 linyisonger
             * @date 	 2025-02-23
             */
            async function drawFrame(cvs, frame, avatar) {
                /** @type {CanvasRenderingContext2D } */
                let ctx = cvs.getContext('2d')
                let roleImg = await loadImage(frame.url)
                let avatarImg = await loadImage(avatar)
                ctx.clearRect(0, 0, cvs.width, cvs.height)
                ctx.drawImage(roleImg, 0, 0, cvs.width, cvs.height)
                let avatarWidth = 40 * ZOOM_OUT
                ctx.drawImage(avatarImg, (frame.avatar.x * ZOOM_OUT - avatarWidth / 2), (frame.avatar.y * ZOOM_OUT - avatarWidth / 2), avatarWidth, avatarWidth)
            }
        }

        init()






    </script>

</body>

</html>